//--------------------------------------------------------------------
//
//  Laboratory 4                                           listarr.cpp
//
//  Class implementation of the Ordered List ADT
//
//--------------------------------------------------------------------

#ifndef LISTARR2_CPP
#define LISTARR2_CPP

#include <iostream>
#include <stdexcept>
#include <new>
#include "listarr2.h"
using namespace std;

    // Constructor
    template < class DT >
    aList<DT>::aList (int maxNumber){
    	if (maxNumber > defMaxListSize){
    		throw bad_alloc();
    	} else{
    	    size=0;
    	    cursor=-1;
    	    maxSize = maxNumber;
    	    dataItems = new DT[maxSize];
        }
    }

    // Destructor
    template < class DT >
    aList<DT>::~aList (){
    	delete [] dataItems;
    }

    // List manipulation operations
    template < class DT >
    void aList<DT>::insert ( const DT &newDataItem ){    // Insert after cursor
    	if (isFull()){
            throw logic_error("List Full!");
    	} else if(isEmpty()) {
    	    dataItems[0]=newDataItem;
    	    size++;
    	    cursor=0;
    	} else {
    	    for(int i=size; i>cursor+1; i--){
    		dataItems[i]=dataItems[i-1];
    	    }
    	    cursor++;
            dataItems[cursor]=newDataItem;
    	    size++;
        }
    }
    
    template < class DT >
    void aList<DT>::remove () {                                // Remove data item
    	if (isEmpty()){
            throw logic_error("List Empty!");
    	} else {
    	    for(int i=cursor; i<size-1; i++)
    		dataItems[i]=dataItems[i+1];
    	    size--;
    	    if (cursor==size)
    	        cursor=0;
        }
    }

    template < class DT >
    void aList<DT>::replace ( const DT &newDataItem ){   // Replace data item
    	if (isEmpty()){
            throw logic_error("List Empty!");
    	} else{
    	    dataItems[cursor]=newDataItem;
        }
    }

    template < class DT >
    void aList<DT>::clear (){                                 // Clear list
    	size=0;                                    // Set size and cursor to 
    	cursor=-1;                                 //   initial condition
    }
    
    // List status operations
    template < class DT >
    bool aList<DT>::isEmpty () const{                   // List is empty
    	return (size == 0);                        //  if size = 0
    }

    template < class DT >
    bool aList<DT>::isFull () const{                    // List is full
    	return (size == maxSize);                  //  if size = maxListSize
    }

    // List iteration operations
    template < class DT >
    void aList<DT>::gotoBeginning () {            // Go to beginning
    	if (isEmpty()) {
    		throw logic_error("List empty!");
    	} else {
    		cursor = 0;
    	}
    }
    	
    template < class DT >
    void aList<DT>::gotoEnd (){                  // Go to end
    	if (isEmpty()) {
    		throw logic_error("List empty!");
    	} else {
    		cursor = size-1;
    	}
    }
    
    template < class DT >
    bool aList<DT>::gotoNext (){                 // Go to next data item
    	if (isEmpty()) {
    		throw logic_error("List empty!");
    	} else if (cursor == size-1){
    		return false;
    	} else {
    		cursor++;
    		return true;
    	}
    }

    template < class DT >
    bool aList<DT>::gotoPrior (){                         // Go to prior data item
    	if (isEmpty()) {
    		throw logic_error("List empty!");
    	} else if (cursor == 0){
    		return false;
    	} else {
    		cursor--;
    		return true;
    	}
    }

    template < class DT >
    DT aList<DT>::getCursor () const{               // Return data item
    	if (isEmpty()) {
    		throw logic_error("List empty!");
    	} else {
    		return dataItems[cursor];
    	}
    }

    // Output the list structure -- used in testing/debugging
//void List::showStructure () const

#endif // #ifndef LISTARR2_CPP


